package gov.gfbzb.advice.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import gov.gfbzb.advice.controller.dto.LoginDTO;
import gov.gfbzb.advice.controller.dto.UserDTO;
import gov.gfbzb.advice.controller.vo.UserVO;
import gov.gfbzb.advice.entity.Enum.UserRoleEnum;
import gov.gfbzb.advice.entity.JwtProperties;
import gov.gfbzb.advice.entity.User;
import gov.gfbzb.advice.exception.BusinessException;
import gov.gfbzb.advice.exception.ErrorCode;
import gov.gfbzb.advice.mapper.UserMapper;
import gov.gfbzb.advice.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import gov.gfbzb.advice.util.JwtUtil;
import gov.gfbzb.advice.util.StringUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * UserServiceImpl 服务实现类
 * @author 小宇
 * @since 2025-07-05
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private JwtProperties jwtProperties;

    @Override
    public Boolean register(UserDTO userDTO) {
        // 判断账号是否已存在
        String phone = userDTO.getPhone();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        User existUser = this.getOne(queryWrapper);
        if (existUser != null){
            throw new BusinessException(400,"手机号已存在");
        }
        // 密码md5加密
        String md5PassWord = StringUtil.md5(userDTO.getPassword());
        userDTO.setPassword(md5PassWord);
        // 没传角色设置普通角色
        if (StringUtils.isBlank(userDTO.getRole())){
            userDTO.setRole(UserRoleEnum.USER.getValue());
        }
        // 复制属性
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        // 保存
        return this.save(user);
    }

    @Override
    public UserVO login(LoginDTO loginDTO) {
        // 手机号
        String phone = loginDTO.getPhone();
        // 用户输入密码
        String password = loginDTO.getPassword();
        // md5密码
        String md5PassWord = StringUtil.md5(password);
        // 获取验证码时的时间戳
        String timestamp = loginDTO.getTimestamp();
        // 用户输入的验证码
        String code = loginDTO.getCode();
        // 验证码字母转小写
        code = code.toLowerCase();
        // 保存的验证码
        String rightCode = (String)redisTemplate.opsForValue().getAndDelete(timestamp);
        if (rightCode == null){
            throw new BusinessException(400,"验证码已过期，请刷新");
        }
        if (!rightCode.equals(code)){
            throw new BusinessException(400,"验证码错误");
        }
        // 获取用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        queryWrapper.eq("password", md5PassWord);
        User user = this.getOne(queryWrapper);
        if (user == null){
            throw new BusinessException(400,"用户名或密码错误");
        }
        // 被禁用用户不得登录
        if (user.getUserStatus()==1){
            throw new BusinessException(400,"用户已禁用");
        }
        // 转换 前端显示对象
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        // 生成token
        userVO.setToken(this.generateToken(user));
        return userVO;
    }

    @Override
    public Claims getClaims() {
        // 获取request
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        // 从请求头中获取token
        String token = request.getHeader("token");
        // 没有token返前端无权限
        if (token == null || token.trim().isEmpty()){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }

        return JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
    }

    @Override
    public String generateToken(User user){
        Map<String, Object> map = new HashMap<>();
        map.put("id", user.getId());
        map.put("phone", user.getPhone());
        map.put("role", user.getRole());
        return JwtUtil.createJwt(jwtProperties.getUserSecretKey(), map);
    }

    @Override
    public String getCheckData(String timestamp) {
        // 生成验证码
        String checkData = StringUtil.getCheckData(6);
        // 存储在redis 120秒过期
        redisTemplate.opsForValue().set(timestamp,checkData,120, TimeUnit.SECONDS);
        return checkData;
    }
}